package com.panopset.swing;

import static com.panopset.Util.dump;
import static com.panopset.Util.x;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import com.panopset.centralen.resource.Favicon;
import com.panopset.gui.PopupBox;
import com.panopset.gui.TPanel;
import com.panopset.gui.TypicalDialog;
import com.panopset.gui.container.PanTextField;
import com.panopset.swing.FontManager.Size;

/**
 * Application frame that provides document to GUI scaffolding.
 *
 * @author Karl Dinwiddie
 *
 */
public abstract class App {
	
	public static App app;

	
	public static void main(String... s) throws Exception {
		new App(null) {

			@Override
			public Component createMainPanel() {
				TPanel p = new TPanel();
				PanTextField tf = new PanTextField(20, "test", "test");
				p.add(tf.getPanel());
				return p;
			}

			@Override
			protected PopupBox getAboutBox() {
				// TODO Auto-generated method stub
				return new PopupBox(new TPanel(), new Dimension(40,40), 
						f.getFrame());
			}
			
            @Override
		    public final String getApplicationName() {
            	return "TestApp";
            }
		}.show();
	}
	
	public void quit() {
		f.quit();
		App.app.s.flush();
	}
	
	public void show() {
		App.app.s.load();
		fontManager.setSize(s.get(FontManager.KEY));
		f.show();
	}
	

    public String home;
    public String getHome() {
    	if (home == null) {
        	home = System.getenv().get("HOMEDRIVE");
        	if (home == null) {
        		home = System.getProperty("user.home");
        		if (home == null) {
        			home = "";
        		}
        		if (home.indexOf(":") == 1) {
        			home = home.substring(0, 2);
        		}
        	}
    	}
    	return home;
    }
    
    /**
     * Simple frame.
     */
    public final SimpleFrame f;

    /**
     * Favicon.
     */
    public Favicon icon;

	protected abstract PopupBox getAboutBox();

    /**
     * Scaffolding.
     */
    public final Scaffolding s = new Scaffolding();

    public final FontManager fontManager = new FontManager();
    
    /**
     * @param defaultPropertiesFileName
     *            Default properties file name.
     * @param favicon
     *            Frame 16x16 favicon.
     * @param aboutBox
     *            About box.
     * @param mainPanel
     *            Main panel.
     */
    public App(
            final Favicon favicon) {
    	app = this;
        icon = favicon;
        f = new SimpleFrame();
    }

    /**
     * Menu bar.
     */
    private JMenuBar mb;

    /**
     * @return Menu bar.
     */
    public JMenuBar getMenuBar() {
        if (mb == null) {
            mb = new MessageMenuBar();
            mb.add(createFileMenu());
            mb.add(createFontMenu());
            mb.add(createHelpMenu());
        }
        return mb;
    }

    /**
     * Override to add menus in between the File and Help menus.
     *
     * @param menuBar
     *            Menu bar.
     */
    protected void addMiddleMenus(final JMenuBar menuBar) {
        // Nothing to do for default behavior.
    }

    /**
     * Show about box.
     */
    public final synchronized void doAbout() {
        getAboutBox().show();
    }

    /**
     * Do system info.
     */
    public final synchronized void doSystemInfo() {
        new TypicalDialog.Builder(x("System Information")).centerPanel(
                new SysInfoPanel().getGui()).construct().display();
    }

    /**
     * Do Java Properties.
     */
    public final synchronized void doEnvInfo() {
        TypicalDialog.dspdlg("System Environment Variables", dump(System
                .getenv()));
    }

    /**
     * Do Java Properties.
     */
    public final synchronized void doJavaProperties() {
        TypicalDialog.dspdlg("Java System Properties", dump(System
                .getProperties()));
    }

    /**
     * Do show log.
     */
    public final synchronized void doShowLog() {
        TypicalDialog.dspdlg("Log", com.panopset.Util.getLog());
    }

    /**
     * Application name.
     */
    private String applicationName;

    /**
     * @return Application name.
     */
    public String getApplicationName() {
        if (applicationName == null) {
            applicationName = this.getClass().getSimpleName();
        }
        return applicationName;
    }

    /**
     * Use this if you don't want the simple class name to be the Application
     * name.
     *
     * @param newName
     *            New application name.
     */
    public final void setApplicationName(final String newName) {
        applicationName = newName;
    }

    /**
     * @return help menu.
     */
    private JMenu createHelpMenu() {
        JMenu menu = new JMenu("Help");
        menu.setMnemonic(KeyEvent.VK_H);
        fontManager.registerComponent(menu,
               FontManager.FontType.plainArial);

        JMenuItem mi = new JMenuItem(x("About") + " " + getApplicationName());
        mi.setMnemonic(KeyEvent.VK_A);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doAbout();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Java Properties"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doJavaProperties();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("System Information"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doSystemInfo();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Environment Variables"));
        mi.setMnemonic(KeyEvent.VK_E);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doEnvInfo();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem(x("Log"));
        mi.setMnemonic(KeyEvent.VK_J);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                doShowLog();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        return menu;
    }

    /**
     * @param size
     *            Size.
     */
    private void setSize(final Size size) {
        fontManager.setSize(size);
        s.put(FontManager.KEY, "" + size.getValue());
    }

    /**
     * @return file menu.
     */
    private JMenu createFontMenu() {
        JMenu menu = new JMenu("Font");
        for (final FontManager.Size size : FontManager.Size.values()) {
            JMenuItem mi = new JMenuItem(size.name());
            mi.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent e) {
                    setSize(size);
                }
            });
            fontManager.registerComponent(mi,
                   FontManager.FontType.plainArial);
            menu.add(mi);
        }
        fontManager.registerComponent(menu,
               FontManager.FontType.plainArial);
        return menu;
    }

    /**
     * @return file menu.
     */
    private JMenu createFileMenu() {
        JMenu menu = new JMenu("File");
        menu.setMnemonic(KeyEvent.VK_F);
        fontManager.registerComponent(menu,
               FontManager.FontType.plainArial);

        JMenuItem mi = new JMenuItem("New");
        mi.setMnemonic(KeyEvent.VK_N);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                s.doNew();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem("Open");
        mi.setMnemonic(KeyEvent.VK_O);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                s.doOpen();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem("Save");
        mi.setMnemonic(KeyEvent.VK_S);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                s.doSave();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem("Save as");
        mi.setMnemonic(KeyEvent.VK_A);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                s.doSaveAs();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        mi = new JMenuItem("Quit");
        mi.setMnemonic(KeyEvent.VK_Q);
        mi.addActionListener(new ActionListener() {

            public void actionPerformed(final ActionEvent e) {
                quit();
            }
        });
        fontManager.registerComponent(mi,FontManager.FontType.plainArial);
        menu.add(mi);

        return menu;
    }

	public abstract Component createMainPanel();
}
